# -*- coding: utf-8 -*-
# @File     : api.py
# @Author   : bingjia
# @Time     : 2020/8/6 18:43
# @Desc     : 数据api视图
import os
import zipfile
from django.apps import apps
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django.shortcuts import get_list_or_404, get_object_or_404

from operation.base.api import viewsets
from operation.base.api import response
from operation.base.api import exceptions as exc
from operation.base.api.utils.decorators import list_route

from . import models
from . import servers
from . import validators
from . import serializers
from . import permissions


class DataViewSet(viewsets.ModelViewSet):
    """
    数据视图
    """
    queryset = models.SrcData.objects.all()
    "验证"
    validator_class = validators.DataValidator
    "序列化"
    serializer_class = serializers.DataSerializer
    "权限"
    permission_classes = (permissions.DataPermission,)

    def list(self, request, *args, **kwargs):
        """
        群查
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        resource_id = kwargs.get("resource_id", None)
        project_model = apps.get_model("projects", "Project")
        project_object = get_object_or_404(project_model.objects.all(), pk=resource_id)

        self.check_permissions(request, 'list', project_object)

        data_obj = get_object_or_404(self.get_queryset(), project=project_object)
        if data_obj:
            serializer = self.get_serializer(data_obj)
            return response.Ok(serializer.data)
        else:
            return response.Ok({"message": "Have no data"})

    @list_route(methods=["POST"])
    def check_file(self, request, *args, **kwargs):
        """
        校验文件
        """
        exist_state = True

        file_name = request.data.get("fileName")
        resource_id = kwargs.get("resource_id", None)

        store_path = os.path.join(settings.ROOT_PATH, (settings.STATIC_URL)[1:-1], settings.PROJECT_PATH, resource_id,
                                  "data", "src")
        output_path = os.path.join(settings.ROOT_PATH, (settings.STATIC_URL)[1:-1], settings.PROJECT_PATH, resource_id,
                                   "data", "output")
        if not os.path.exists(output_path):
            os.makedirs(output_path)
        if not os.path.exists(store_path):
            exist_state = False
            os.makedirs(store_path)
        else:
            if not os.path.exists(os.path.join(store_path, file_name)):
                exist_state = False

        return response.Ok({'isExist': exist_state})

    @list_route(methods=["POST"])
    def check_chunk(self, request, *args, **kwargs):
        """
        分片校验
        """
        resource_id = kwargs.get("resource_id", None)
        project_model = apps.get_model("projects", "Project")
        project_object = get_object_or_404(project_model.objects.all(), pk=resource_id)

        self.check_permissions(request, "check_chunk", project_object)

        try:
            chunk_size = request.data.get("chunkSize")
            if chunk_size == "0":
                return response.Ok({'ifExist': True})

            md5 = request.data.get("fileMd5")
            chunk = request.data.get("chunk")
            file_name = "%s-%s" % (md5, chunk)

            "文件路径不存在则创建"
            file_dir = os.path.join(settings.ROOT_PATH, (settings.STATIC_URL)[1:-1], settings.PROJECT_PATH, resource_id,
                                    "data", "src")
            if file_name in os.listdir(file_dir):
                is_exist = True
            else:
                is_exist = False
        except Exception as e:
            print(e)
        else:
            return response.Ok({'isExist': is_exist})

    @list_route(methods=["POST"])
    def upload_chunk(self, request, *args, **kwargs):
        """
        分片上传
        """
        resource_id = kwargs.get("resource_id", None)
        project_model = apps.get_model("projects", "Project")
        project_object = get_object_or_404(project_model.objects.all(), pk=resource_id)

        # self.check_permissions(request, "upload_chunk", project_object)

        "验证数据"
        try:
            md5 = request.data.get("md5", None)
            file = request.data.get("file", None)
            chunk = request.data.get("chunk", "0")

            file_name = "%s-%s" % (md5, chunk)

            file_dir = os.path.join(settings.ROOT_PATH, (settings.STATIC_URL)[1:-1], settings.PROJECT_PATH, resource_id,
                                    "data", "src")
            if not os.path.exists(file_dir):
                os.makedirs(file_dir)

            with open(os.path.join(file_dir, file_name), "wb") as f:
                for i in file.chunks():
                    f.write(i)
        except Exception as e:
            return response.Ok({'upload_part': False})
        else:
            return response.Ok({'upload_part': True})

    @list_route(methods=["POST"])
    def merge_chunk(self, request, *args, **kwargs):
        """
        分片合并
        """
        resource_id = kwargs.get("resource_id", None)
        project_model = apps.get_model("projects", "Project")
        project_object = get_object_or_404(project_model.objects.all(), pk=resource_id)

        # self.check_permissions(request, "merge_chunk", project_object)

        try:
            chunk = 0
            md5 = request.data.get("fileMd5")
            file_id = request.data.get("fileId")
            file_name = request.data.get("fileName")

            data_path = os.path.join(settings.ROOT_PATH, settings.STATIC_URL[1:-1], settings.PROJECT_PATH,
                                     resource_id, "data", "src", file_name)

            with open(data_path, "wb") as fp:
                while True:
                    try:
                        filename = os.path.join(settings.ROOT_PATH, settings.STATIC_URL[1:-1], settings.PROJECT_PATH,
                                                resource_id, "data", "src",
                                                "{}-{}".format(md5, chunk))
                        with open(filename, "rb") as f:
                            fp.write(f.read())
                        os.remove(filename)
                    except Exception as e:
                        break
                    chunk += 1
                # 文件解压
                if os.path.splitext(data_path)[1] == ".zip":
                    file_zip = zipfile.ZipFile(data_path, 'r')
                    for file in file_zip.namelist():
                        file_zip.extract(file,
                                         os.path.join(settings.ROOT_PATH, (settings.STATIC_URL)[1:-1],
                                                      settings.PROJECT_PATH, resource_id, "data", "src"))
                    file_zip.close()
                    # 删除压缩文件
                    # os.remove(data_path)


                # 统计图片数量
                data_model = models.SrcData
                data = data_model(
                    name=project_object.name,
                    data_size=24,
                    project=project_object,
                    thermal_image=24,
                    visible_image=24,
                )
                data.save()
                # 更改项目图片状态
                project_object.image_status = "1"
                project_object.save()

        except Exception as e:
            print(e)
        else:
            print('-------------merge_chunk-----------------')

        return response.Created({'upload': True, 'fileName': 'xx', 'fileId': 22})


class DataAdminViewSet(viewsets.ModelViewSet):
    """
    数据管理视图
    """
    queryset = models.SrcData.objects.all()
    "验证"
    validator_class = validators.DataValidator
    "序列化"
    serializer_class = serializers.SrcDataAdminSerializer
    "权限"
    permission_classes = (permissions.SrcDataAdminPermission,)

    def list(self, request, *args, **kwargs):
        """
        群查（项目数据情况）
        """
        data_obj_list = self.get_queryset()

        self.check_permissions(request, 'list', None)

        page = self.paginate_queryset(data_obj_list)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        else:
            serializer = self.get_serializer(data_obj_list, many=True)

        return response.Ok(serializer.data)
